﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using System.Collections;

namespace Helix_Network_Supervisor_3
{
    class ChannelMap
    {
        #region Fields

        private ApplicationSettings appSettings = new ApplicationSettings();
        private bool channelMapNeedsToBeSaved = false;
        private string saveChannelMapFilePath = "";
        private string currentChannelMapFileName = "New Channel Map";
        private int numberOfHelixSystems = 0;
        private bool editDeleteButtonEnabled = false;
        private Hashtable[] helixSystemGroupTables;
        private FileManipulator fm = new FileManipulator();
        private SaveFileDialog saveFileDialog = new SaveFileDialog();

        #endregion Fields

        #region Ctor

        #endregion Ctor

        #region Properties

        public bool EditDeleteButtonEnabled
        {
            get
            {
                return (editDeleteButtonEnabled);
            }
        }

        public bool ChannelMapNeedsToBeSaved
        {
            get
            {
                return (channelMapNeedsToBeSaved);
            }
        }

        public int NumberOfHelixSystems
        {
            get
            {
                return (numberOfHelixSystems);
            }
        }

        public string CurrentChannelMapFileName
        {
            get
            {
                return (currentChannelMapFileName);
            }
        }

        #endregion Properties

        #region Public Methods

        /// <summary>
        /// Populate the Channel Map List View with the Currently Saved Channel Maps
        /// </summary>
        /// <param name="channelMapListView"></param>
        public void PopulateSavedChannelMapListView(ListView savedChannelMapListView)
        {
            savedChannelMapListView.Clear();

            savedChannelMapListView.Columns.Add("File Name (Double Click to Open)", 200, HorizontalAlignment.Left);
            savedChannelMapListView.Columns.Add("File Path", 1, HorizontalAlignment.Left);

            string channelMapPath = appSettings.channelMapFilePath;

            try
            {
                DirectoryInfo di = new DirectoryInfo(channelMapPath);
                FileInfo[] arrFiles = di.GetFiles();

                string[] listItems = new string[2];
                string fileName = "";
                foreach (FileInfo tempFile in arrFiles)
                {
                    fileName = tempFile.Name;
                    fileName.ToUpper();
                    if (!fileName.Equals("PAGEFILE.SYS"))
                    {
                        int iImage = 1;
                        string fileExtension = tempFile.Extension;

                        listItems[0] = fileName;
                        listItems[1] = channelMapPath;

                        ListViewItem lviItem = new ListViewItem(listItems, iImage);

                        savedChannelMapListView.Items.Add(lviItem);
                    }
                }
            }
            catch
            {
            }

        }

        /// <summary>
        /// Initialize the Channel Map Control with the Proper Column Headers
        /// </summary>
        /// <param name="channelMapListView"></param>
        public void InitChannelMapControl(ListView channelMapListView)
        {
            channelMapListView.Clear();
            channelMapListView.Columns.Add("Helix System", 0, HorizontalAlignment.Left);
            channelMapListView.Columns.Add("Channel Bank", 100, HorizontalAlignment.Left);
            channelMapListView.Columns.Add("Function", 100, HorizontalAlignment.Left);
            channelMapListView.Columns.Add("Start Channel", 100, HorizontalAlignment.Left);
            channelMapListView.Columns.Add("End Channel", 100, HorizontalAlignment.Left);
            channelMapListView.Columns.Add("System Num", 0, HorizontalAlignment.Left);


            channelMapListView.Groups.Clear();

            editDeleteButtonEnabled = false;
            numberOfHelixSystems = 0;
            saveChannelMapFilePath = "";
            currentChannelMapFileName = "New Channel Map";
            channelMapNeedsToBeSaved = false;
        }

        /// <summary>
        /// Open the Channel Map Selected in the Saved Channel Map List View
        /// </summary>
        /// <param name="channelMapListView"></param>
        /// <param name="selectedFile"></param>
        public bool OpenChannelMap(ListView channelMapListView, string openChannelMapFilePath)
        {
            if (channelMapNeedsToBeSaved)
            {
                DialogResult dR = MessageBox.Show("The current channel map has not been saved.  \rSave the current channel map?",
                    "Helix Channel Map Warning", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
                if (dR == DialogResult.Yes)
                {
                    SaveChannelMap(channelMapListView);
                }
                else if (dR == DialogResult.Cancel)
                {
                    return false;
                }
            }

            InitChannelMapControl(channelMapListView);

            saveChannelMapFilePath = openChannelMapFilePath;

            numberOfHelixSystems = 0;

            try
            {
                ListView.ListViewItemCollection lvicToOpen = fm.OpenChannelMapFile(openChannelMapFilePath);

                foreach (ListViewItem lvi in lvicToOpen)
                {
                    numberOfHelixSystems++;
                    lvi.UseItemStyleForSubItems = false;
                    ListViewItem.ListViewSubItemCollection subItems = lvi.SubItems;
                    channelMapListView.Items.Add((ListViewItem)lvi.Clone());
                }

                numberOfHelixSystems = numberOfHelixSystems / 4;

                //editHelixButton.Enabled = true;

                helixSystemGroupTables = new Hashtable[channelMapListView.Columns.Count];

                for (int column = 0; column < channelMapListView.Columns.Count; column++)
                {
                    // Create a hash table containing all the groups 
                    // needed for a single column.
                    helixSystemGroupTables[column] = CreateHelixSystemGroupsTable(channelMapListView, column);
                }

                SetHelixSystemGroups(channelMapListView, 0);

                if (numberOfHelixSystems > 0)
                {
                    currentChannelMapFileName = Path.GetFileName(openChannelMapFilePath);
                    editDeleteButtonEnabled = true;
                }

                return true;
            }
            catch
            {
                return false;
            }

        } //End Open Channel Map

        /// <summary>
        /// Create a New Chanel Map
        /// </summary>
        /// <param name="channelMapListview"></param>
        public bool NewChannelMap(ListView channelMapListview)
        {
            if (channelMapNeedsToBeSaved)
            {
                DialogResult dR = MessageBox.Show("The current channel map has not been saved.  \rSave the current channel map?",
                    "Helix Channel Map Warning", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
                if (dR == DialogResult.Yes)
                {
                    SaveChannelMap(channelMapListview);
                }
                else if (dR == DialogResult.Cancel)
                {
                    return false;
                }
            }
            InitChannelMapControl(channelMapListview);
            return true;
        }
        
        /// <summary>
        /// Save the Current Channel Map
        /// </summary>
        /// <param name="channelMapListView"></param>
        /// <returns>True of the Channel Map was Properly Saved</returns>
        public bool SaveChannelMap(ListView channelMapListView)
        {
            //Get the file name
            string channelMapFileName = "";
            if (saveChannelMapFilePath == "")
            {
                saveFileDialog.InitialDirectory = appSettings.channelMapFilePath;
                saveFileDialog.FileName = channelMapFileName;
                saveFileDialog.DefaultExt = "map";
                saveFileDialog.Filter = "Helix Channel Map Files|*.map";
                //Call the SaveFileDialog
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    saveChannelMapFilePath = saveFileDialog.FileName;
                    channelMapFileName = Path.GetFileName(saveChannelMapFilePath);
                    saveChannelMapFilePath = appSettings.channelMapFilePath + @"\" + channelMapFileName;

                }
                else
                {
                    return false;
                }
            }
            //Save the schedule to a text file
            ListView.ListViewItemCollection channelMapList = channelMapListView.Items;

            fm.SaveChannelMap(channelMapList, saveChannelMapFilePath);

            channelMapNeedsToBeSaved = false;
            currentChannelMapFileName = Path.GetFileName(saveChannelMapFilePath);
            return true;
        }

        /// <summary>
        /// Save the Current Channel Map with a New Name
        /// </summary>
        /// <param name="channelMapListView"></param>
        /// <returns>True if Channel Map was Properly Saved</returns>
        public bool SaveAsChannelMap(ListView channelMapListView)
        {
            string originalFilePath = saveChannelMapFilePath;
            saveChannelMapFilePath = "";

            if (SaveChannelMap(channelMapListView) == true)
            {
                currentChannelMapFileName = Path.GetFileName(saveChannelMapFilePath);
                return true;
            }
            else
            {
                saveChannelMapFilePath = originalFilePath;
                return false;
            }
        }

        /// <summary>
        /// Add a Helix System to the Current Channel Map
        /// </summary>
        /// <param name="channelMapListView"></param>
        public void addHelixSystem(ListView channelMapListView)
        {
            ChannelMapForm ChMapForm = new ChannelMapForm();

            ChMapForm.updateHelixSystemLabel(numberOfHelixSystems + 1);

            if (ChMapForm.ShowDialog() == DialogResult.OK)
            {
                numberOfHelixSystems++;
                //Get and insert Channel Bank 1
                ListViewItem newSystemChB1 = new ListViewItem("Helix System " + numberOfHelixSystems.ToString());
                newSystemChB1.SubItems.Add("Channel Bank 1");
                newSystemChB1.SubItems.Add(ChMapForm.chB1Function);
                if (ChMapForm.chB1Function != "Unused")
                {
                    newSystemChB1.SubItems.Add(ChMapForm.chB1StartChannel.ToString());
                    newSystemChB1.SubItems.Add(ChMapForm.chB1EndChannel.ToString());
                }
                else
                {
                    newSystemChB1.SubItems.Add("N/A");
                    newSystemChB1.SubItems.Add("N/A");
                }
                newSystemChB1.SubItems.Add(numberOfHelixSystems.ToString());

                channelMapListView.Items.Add(newSystemChB1);

                //Get and insert Channel Bank 2
                ListViewItem newSystemChB2 = new ListViewItem("Helix System " + numberOfHelixSystems.ToString());
                newSystemChB2.SubItems.Add("Channel Bank 2");
                newSystemChB2.SubItems.Add(ChMapForm.chB2Function);
                if (ChMapForm.chB2Function != "Unused")
                {
                    newSystemChB2.SubItems.Add(ChMapForm.chB2StartChannel.ToString());
                    newSystemChB2.SubItems.Add(ChMapForm.chB2EndChannel.ToString());
                }
                else
                {
                    newSystemChB2.SubItems.Add("N/A");
                    newSystemChB2.SubItems.Add("N/A");
                }

                newSystemChB2.SubItems.Add(numberOfHelixSystems.ToString());

                channelMapListView.Items.Add(newSystemChB2);

                //Get and insert Channel Bank 3
                ListViewItem newSystemChB3 = new ListViewItem("Helix System " + numberOfHelixSystems.ToString());
                newSystemChB3.SubItems.Add("Channel Bank 3");
                newSystemChB3.SubItems.Add(ChMapForm.chB3Function);
                if (ChMapForm.chB3Function != "Unused")
                {
                    newSystemChB3.SubItems.Add(ChMapForm.chB3StartChannel.ToString());
                    newSystemChB3.SubItems.Add(ChMapForm.chB3EndChannel.ToString());
                }
                else
                {
                    newSystemChB3.SubItems.Add("N/A");
                    newSystemChB3.SubItems.Add("N/A");
                }

                newSystemChB3.SubItems.Add(numberOfHelixSystems.ToString());

                channelMapListView.Items.Add(newSystemChB3);

                //Get and insert Channel Bank 4
                ListViewItem newSystemChB4 = new ListViewItem("Helix System " + numberOfHelixSystems.ToString());
                newSystemChB4.SubItems.Add("Channel Bank 4");
                newSystemChB4.SubItems.Add(ChMapForm.chB4Function);
                if (ChMapForm.chB4Function != "Unused")
                {
                    newSystemChB4.SubItems.Add(ChMapForm.chB4StartChannel.ToString());
                    newSystemChB4.SubItems.Add(ChMapForm.chB4EndChannel.ToString());
                }
                else
                {
                    newSystemChB4.SubItems.Add("N/A");
                    newSystemChB4.SubItems.Add("N/A");
                }

                newSystemChB4.SubItems.Add(numberOfHelixSystems.ToString());

                channelMapListView.Items.Add(newSystemChB4);



                helixSystemGroupTables = new Hashtable[channelMapListView.Columns.Count];

                for (int column = 0; column < channelMapListView.Columns.Count; column++)
                {
                    // Create a hash table containing all the groups 
                    // needed for a single column.
                    helixSystemGroupTables[column] = CreateHelixSystemGroupsTable(channelMapListView, column);
                }

                SetHelixSystemGroups(channelMapListView, 0);

                channelMapNeedsToBeSaved = true;
            }

        }//end addHelixSystem

        /// <summary>
        /// Delete the Last Helix System in the Channel Map
        /// </summary>
        /// <param name="channelMapListView"></param>
        public void deleteHelixSystem(ListView channelMapListView)
        {
            ListView.ListViewItemCollection helixList = channelMapListView.Items;

            for (int index = 0; index < helixList.Count; index++)
            {
                if (helixList[index].SubItems[0].Text == ("Helix System " + numberOfHelixSystems.ToString()))
                {
                    helixList[index].Remove();
                }

                if (helixList[index].SubItems[0].Text == ("Helix System " + numberOfHelixSystems.ToString()))
                {
                    helixList[index].Remove();
                }

                if (helixList[index].SubItems[0].Text == ("Helix System " + numberOfHelixSystems.ToString()))
                {
                    helixList[index].Remove();
                }

                if (helixList[index].SubItems[0].Text == ("Helix System " + numberOfHelixSystems.ToString()))
                {
                    helixList[index].Remove();
                    numberOfHelixSystems--;
                    channelMapNeedsToBeSaved = true;
                    if (numberOfHelixSystems == 0)
                    {
                        channelMapNeedsToBeSaved = false;
                        //editHelixButton.Enabled = false;
                        //deleteHelixButton.Enabled = false;
                        //saveChMapTSButton.Enabled = false;
                        //saveChMapTSMenuItem.Enabled = false;
                        //saveAsChMapTSMenuItem.Enabled = false;
                    }
                }
            }
        }//end deleteHelixSystem

        /// <summary>
        /// Edit the Selected Helix System
        /// </summary>
        /// <param name="channelMapListView"></param>
        public void editHelixSystem(ListView channelMapListView)
        {
            try
            {
                ListView.SelectedListViewItemCollection selectedHelix = channelMapListView.SelectedItems;

                ListViewItem selectedItem = selectedHelix[0];

                ChannelMapForm editHelix = new ChannelMapForm();

                editHelix.Text = "Edit Helix System";

                int selectedHelixSystem = 0;
                try
                {
                    selectedHelixSystem = (int.Parse(selectedItem.SubItems[5].Text));
                }
                catch
                {

                }
                editHelix.updateHelixSystemLabel(selectedHelixSystem);

                ListView.ListViewItemCollection helixList = channelMapListView.Items;


                for (int index = 0; index < helixList.Count; index++)
                {
                    if (helixList[index].SubItems[0].Text == selectedItem.SubItems[0].Text)
                    {
                        switch (helixList[index].SubItems[1].Text)
                        {
                            case "Channel Bank 1":
                                editHelix.chB1Function = helixList[index].SubItems[2].Text;
                                if (helixList[index].SubItems[2].Text != "Unused")
                                {
                                    editHelix.chB1StartChannel = int.Parse(helixList[index].SubItems[3].Text);
                                    editHelix.chB1EndChannel = int.Parse(helixList[index].SubItems[4].Text);
                                }
                                break;

                            case "Channel Bank 2":
                                editHelix.chB2Function = helixList[index].SubItems[2].Text;
                                if (helixList[index].SubItems[2].Text != "Unused")
                                {
                                    editHelix.chB2StartChannel = int.Parse(helixList[index].SubItems[3].Text);
                                    editHelix.chB2EndChannel = int.Parse(helixList[index].SubItems[4].Text);
                                }
                                break;

                            case "Channel Bank 3":
                                editHelix.chB3Function = helixList[index].SubItems[2].Text;
                                if (helixList[index].SubItems[2].Text != "Unused")
                                {
                                    editHelix.chB3StartChannel = int.Parse(helixList[index].SubItems[3].Text);
                                    editHelix.chB3EndChannel = int.Parse(helixList[index].SubItems[4].Text);
                                }
                                break;

                            case "Channel Bank 4":
                                editHelix.chB4Function = helixList[index].SubItems[2].Text;
                                if (helixList[index].SubItems[2].Text != "Unused")
                                {
                                    editHelix.chB4StartChannel = int.Parse(helixList[index].SubItems[3].Text);
                                    editHelix.chB4EndChannel = int.Parse(helixList[index].SubItems[4].Text);
                                }
                                break;
                        }
                    }
                }
                if (editHelix.ShowDialog() == DialogResult.OK)
                {
                    //Remove the existing items
                    for (int index = 0; index < helixList.Count; index++)
                    {
                        if (helixList[index].SubItems[0].Text == selectedItem.SubItems[0].Text)
                        {
                            helixList[index].Remove();
                        }
                        if (helixList[index].SubItems[0].Text == selectedItem.SubItems[0].Text)
                        {
                            helixList[index].Remove();
                        }
                        if (helixList[index].SubItems[0].Text == selectedItem.SubItems[0].Text)
                        {
                            helixList[index].Remove();
                        }
                        if (helixList[index].SubItems[0].Text == selectedItem.SubItems[0].Text)
                        {
                            helixList[index].Remove();
                        }
                    }
                    //Get and insert Channel Bank 1
                    ListViewItem newSystemChB1 = new ListViewItem(selectedItem.SubItems[0].Text);
                    newSystemChB1.SubItems.Add("Channel Bank 1");
                    newSystemChB1.SubItems.Add(editHelix.chB1Function);
                    if (editHelix.chB1Function != "Unused")
                    {
                        newSystemChB1.SubItems.Add(editHelix.chB1StartChannel.ToString());
                        newSystemChB1.SubItems.Add(editHelix.chB1EndChannel.ToString());
                    }
                    else
                    {
                        newSystemChB1.SubItems.Add("N/A");
                        newSystemChB1.SubItems.Add("N/A");
                    }

                    newSystemChB1.SubItems.Add(selectedHelixSystem.ToString());

                    channelMapListView.Items.Add(newSystemChB1);

                    //Get and insert Channel Bank 2
                    ListViewItem newSystemChB2 = new ListViewItem(selectedItem.SubItems[0].Text);
                    newSystemChB2.SubItems.Add("Channel Bank 2");
                    newSystemChB2.SubItems.Add(editHelix.chB2Function);
                    if (editHelix.chB2Function != "Unused")
                    {
                        newSystemChB2.SubItems.Add(editHelix.chB2StartChannel.ToString());
                        newSystemChB2.SubItems.Add(editHelix.chB2EndChannel.ToString());
                    }
                    else
                    {
                        newSystemChB2.SubItems.Add("N/A");
                        newSystemChB2.SubItems.Add("N/A");
                    }

                    newSystemChB2.SubItems.Add(selectedHelixSystem.ToString());

                    channelMapListView.Items.Add(newSystemChB2);

                    //Get and insert Channel Bank 3
                    ListViewItem newSystemChB3 = new ListViewItem(selectedItem.SubItems[0].Text);
                    newSystemChB3.SubItems.Add("Channel Bank 3");
                    newSystemChB3.SubItems.Add(editHelix.chB3Function);
                    if (editHelix.chB3Function != "Unused")
                    {
                        newSystemChB3.SubItems.Add(editHelix.chB3StartChannel.ToString());
                        newSystemChB3.SubItems.Add(editHelix.chB3EndChannel.ToString());
                    }
                    else
                    {
                        newSystemChB3.SubItems.Add("N/A");
                        newSystemChB3.SubItems.Add("N/A");
                    }

                    newSystemChB3.SubItems.Add(selectedHelixSystem.ToString());

                    channelMapListView.Items.Add(newSystemChB3);

                    //Get and insert Channel Bank 4
                    ListViewItem newSystemChB4 = new ListViewItem(selectedItem.SubItems[0].Text);
                    newSystemChB4.SubItems.Add("Channel Bank 4");
                    newSystemChB4.SubItems.Add(editHelix.chB4Function);
                    if (editHelix.chB4Function != "Unused")
                    {
                        newSystemChB4.SubItems.Add(editHelix.chB4StartChannel.ToString());
                        newSystemChB4.SubItems.Add(editHelix.chB4EndChannel.ToString());
                    }
                    else
                    {
                        newSystemChB4.SubItems.Add("N/A");
                        newSystemChB4.SubItems.Add("N/A");
                    }

                    newSystemChB4.SubItems.Add(selectedHelixSystem.ToString());

                    channelMapListView.Items.Add(newSystemChB4);

                    //Group the channel banks by Helix System #
                    helixSystemGroupTables = new Hashtable[channelMapListView.Columns.Count];

                    for (int column = 0; column < channelMapListView.Columns.Count; column++)
                    {
                        // Create a hash table containing all the groups 
                        // needed for a single column.
                        helixSystemGroupTables[column] = CreateHelixSystemGroupsTable(channelMapListView, column);
                    }

                    SetHelixSystemGroups(channelMapListView, 0);

                    channelMapNeedsToBeSaved = true;
                }
            }
            catch
            {
                MessageBox.Show("No Helix System was selected", "Helix Channel Map - Error",
     MessageBoxButtons.OK, MessageBoxIcon.Stop);

            }
        }//end editHelixSystem

        #endregion Public Methods

        #region Private Methods

        private void SetHelixSystemGroups(ListView channelMapListView, int column)
        {
            // Remove the current groups.
            channelMapListView.Groups.Clear();

            // Retrieve the hash table corresponding to the column.
            Hashtable groups = (Hashtable)helixSystemGroupTables[column];

            // Copy the groups for the column to an array.
            ListViewGroup[] groupsArray = new ListViewGroup[groups.Count];
            groups.Values.CopyTo(groupsArray, 0);

            // Sort the groups and add them to myListView.
            Array.Sort(groupsArray, new ListViewHelixSystemGroupSorter(channelMapListView.Sorting));
            channelMapListView.Groups.AddRange(groupsArray);

            // Iterate through the items in myListView, assigning each 
            // one to the appropriate group.
            foreach (ListViewItem item in channelMapListView.Items)
            {
                // Retrieve the subitem text corresponding to the column.
                string subItemText = item.SubItems[column].Text;

                // Assign the item to the matching group.
                item.Group = (ListViewGroup)groups[subItemText];
            }
        }

        private Hashtable CreateHelixSystemGroupsTable(ListView channelMapListView, int column)
        {
            // Create a Hashtable object.
            Hashtable groups = new Hashtable();

            // Iterate through the items in channelMapListView.
            foreach (ListViewItem item in channelMapListView.Items)
            {
                // Retrieve the text value for the column.
                string subItemText = item.SubItems[column].Text;

                // If the groups table does not already contain a group
                // for the subItemText value, add a new group using the 
                // subItemText value for the group header and Hashtable key.
                if (!groups.Contains(subItemText))
                {
                    groups.Add(subItemText, new ListViewGroup(subItemText,
                        HorizontalAlignment.Left));
                }
            }

            // Return the Hashtable object.
            return groups;
        }

        private class ListViewHelixSystemGroupSorter : IComparer
        {
            private SortOrder order;

            // Stores the sort order.
            public ListViewHelixSystemGroupSorter(SortOrder theOrder)
            {
                order = theOrder;
            }

            // Compares the groups by header value, using the saved sort
            // order to return the correct value.
            public int Compare(object x, object y)
            {
                int result = String.Compare(
                    ((ListViewGroup)x).Header,
                    ((ListViewGroup)y).Header
                );
                if (order == SortOrder.Ascending)
                {
                    return result;
                }
                else
                {
                    return -result;
                }
            }
        }

        #endregion Private Methods
    }
}
